package cn.mini.mybatis.mybatis.session;


import cn.mini.mybatis.mybatis.binding.MapperRegistry;
import cn.mini.mybatis.mybatis.executor.Executor;
import cn.mini.mybatis.mybatis.executor.SimpleExecutor;
import cn.mini.mybatis.mybatis.executor.resultset.DefaultResultSetHandler;
import cn.mini.mybatis.mybatis.executor.resultset.ResultSetHandler;
import cn.mini.mybatis.mybatis.executor.statementHandler.PreparedStatementHandler;
import cn.mini.mybatis.mybatis.executor.statementHandler.StatementHandler;
import cn.mini.mybatis.mybatis.mapping.BoundSql;
import cn.mini.mybatis.mybatis.mapping.MappedStatement;
import cn.mini.mybatis.mybatis.typehandler.TypeAliasRegistry;

import java.util.HashMap;
import java.util.Map;

/**
 * 配置类
 * 用于管理 Mapper 接口和代理对象的创建
 */
public class Configuration {
    // 持有 MapperRegistry 实例
    private final MapperRegistry mapperRegistry = new MapperRegistry();

    /**
     * 映射的语句，存在Map里
     */
    protected final Map<String, MappedStatement> mappedStatements = new HashMap<>();
    protected final TypeAliasRegistry typeAliasRegistry = new TypeAliasRegistry();


    /**
     * 添加 Mapper 接口
     * @param type Mapper 接口的 Class 对象
     * @param <T> Mapper 接口的类型
     */
    public <T> void addMapper(Class<T> type) {
        mapperRegistry.addMapper(type);
    }
    /**
     * 获取 Mapper 接口的代理对象
     * @param type Mapper 接口的 Class 对象
     * @param sqlSession SqlSession 实例
     * @param <T> Mapper 接口的类型
     * @return Mapper 接口的代理对象
     */
    public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        return mapperRegistry.getMapper(type, sqlSession);
    }

    public void addMappedStatement(MappedStatement ms) {
        mappedStatements.put(ms.getId(), ms);
    }

    public MappedStatement getMappedStatement(String id) {
        return mappedStatements.get(id);
    }

    public boolean hasStatement(String statementName) {
        return mappedStatements.containsKey(statementName);
    }



    public Executor newExecutor() {
        return new SimpleExecutor(this);
    }

    public TypeAliasRegistry getTypeAliasRegistry() {
        return typeAliasRegistry;
    }


    public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement,
                                                Object parameter, ResultSetHandler resultHandler, BoundSql boundSql) {
        return new PreparedStatementHandler(executor, mappedStatement, parameter, resultHandler, boundSql);
    }

    public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, BoundSql boundSql) {
        return new DefaultResultSetHandler(executor, mappedStatement, boundSql);
    }
}
